//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package net.mingsoft.mdiy.biz.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import net.mingsoft.base.biz.impl.BaseBizImpl;
import net.mingsoft.base.dao.IBaseDao;
import net.mingsoft.base.exception.BusinessException;
import net.mingsoft.base.util.BundleUtil;
import net.mingsoft.mdiy.bean.ModelJsonBean;
import net.mingsoft.mdiy.biz.IConfigBiz;
import net.mingsoft.mdiy.biz.IModelBiz;
import net.mingsoft.mdiy.constant.e.ModelCustomTypeEnum;
import net.mingsoft.mdiy.dao.IModelDao;
import net.mingsoft.mdiy.entity.ConfigEntity;
import net.mingsoft.mdiy.entity.ModelEntity;
import net.mingsoft.mdiy.util.ConfigUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("mdiyModelBizImpl")
@Transactional(
        rollbackFor = {Exception.class}
)
public class ModelBizImpl extends BaseBizImpl<IModelDao, ModelEntity> implements IModelBiz {
    @Autowired
    private IModelDao modelDao;
    @Autowired
    private IConfigBiz configBiz;

    public ModelBizImpl() {
    }

    protected IBaseDao getDao() {
        return this.modelDao;
    }

    public boolean importConfig(String customType, ModelJsonBean modelJsonBean) {
        return !StringUtils.isEmpty(customType) && modelJsonBean != null ? this.importModel(customType, modelJsonBean, "") : false;
    }

    public boolean importModel(String customType, ModelJsonBean modelJsonBean, String modelType) {
        if (!StringUtils.isEmpty(customType) && modelJsonBean != null) {
            if (StringUtils.isBlank(modelJsonBean.getTitle())) {
                return false;
            } else {
                LambdaQueryWrapper<ModelEntity> queryWrapper = new LambdaQueryWrapper();
                queryWrapper.eq(StringUtils.isNotBlank(customType), ModelEntity::getModelCustomType, customType)
                        .and((wrapper) -> {

                            wrapper.eq(ModelEntity::getModelName, modelJsonBean.getTitle())
                                    .or()
                                    .eq(StrUtil.isNotBlank(modelJsonBean.getTableName()), ModelEntity::getModelTableName, "mdiy_" + customType + "_" + modelJsonBean.getTableName());
                        });

                List<ModelEntity> modelEntities = this.list(queryWrapper);
                if (CollectionUtil.isNotEmpty(modelEntities)) {
                    return false;
                } else {
                    ModelEntity model = new ModelEntity();
                    model.setModelName(modelJsonBean.getTitle());
                    model.setModelTableName(modelJsonBean.getTableName());
                    model.setModelCustomType(customType);
                    model.setModelIdType(modelJsonBean.getId());
                    String tmpSql = modelJsonBean.getSql();
                    Pattern compile = Pattern.compile(";[\\s\\S]*?(CREATE OR REPLACE[\\s\\S]*;)", 2);
                    Matcher matcher = compile.matcher(tmpSql);
                    if (matcher.find()) {
                        tmpSql = matcher.group(1);
                        modelJsonBean.setSql(modelJsonBean.getSql().replace(tmpSql, ""));
                    } else {
                        tmpSql = "";
                    }

                    String[] formSqls;
                    String[] var11;
                    int var12;
                    int var13;
                    String sql;
                    String createRegex;
                    String alterRegex;
                    Pattern createPattern;
                    Pattern alterPattern;
                    if (customType.equalsIgnoreCase(ModelCustomTypeEnum.MODEL.getLabel())) {
                        model.setModelTableName("MDIY_MODEL_" + modelJsonBean.getTableName());
                        tmpSql = tmpSql.replace("{model}", "MDIY_MODEL_");
                        if (StringUtils.isNotBlank(modelJsonBean.getSql())) {
                            formSqls = modelJsonBean.getSql().replace("{model}", "MDIY_MODEL_").trim().split(";");
                            var11 = formSqls;
                            var12 = formSqls.length;

                            for (var13 = 0; var13 < var12; ++var13) {
                                sql = var11[var13];
                                if (StringUtils.containsAnyIgnoreCase(sql, new CharSequence[]{"CREATE TABLE", "ALTER TABLE"})) {
                                    createRegex = "CREATE[\\s]*TABLE[\\s\\S]*MDIY_MODEL_" + modelJsonBean.getTableName().toUpperCase();
                                    alterRegex = "ALTER[\\s]*TABLE[\\s\\S]*MDIY_MODEL_" + modelJsonBean.getTableName().toUpperCase();
                                    createPattern = Pattern.compile(createRegex);
                                    alterPattern = Pattern.compile(alterRegex);
                                    if (createPattern.matcher(sql.toUpperCase()).find() || alterPattern.matcher(sql.toUpperCase()).find()) {
                                        this.modelDao.excuteSql(sql);
                                        continue;
                                    }
                                }

                                if (!StringUtils.isBlank(sql) && !StrUtil.containsAnyIgnoreCase(sql, new CharSequence[]{"INSERT ", "SELECT ", "UPDATE ", "DELETE ", "DROP ", "ALTER ", "TRUNCATE ", "RENAME "})) {
                                    this.modelDao.excuteSql(sql);
                                }
                            }
                        }
                    }

                    if (customType.equalsIgnoreCase(ModelCustomTypeEnum.FORM.getLabel())) {
                        model.setModelTableName("MDIY_FORM_" + modelJsonBean.getTableName());
                        modelJsonBean.setSql(modelJsonBean.getSql().replaceAll("ALTER TABLE[\\s\\S]*?UNIQUE[\\s\\S]*?;", ""));
                        tmpSql = tmpSql.replace("{model}", "MDIY_FORM_");
                        formSqls = modelJsonBean.getSql().replace("{model}", "MDIY_FORM_").trim().split(";");
                        var11 = formSqls;
                        var12 = formSqls.length;

                        for (var13 = 0; var13 < var12; ++var13) {
                            sql = var11[var13];
                            if (StrUtil.containsAnyIgnoreCase(sql, new CharSequence[]{"CREATE TABLE", "ALTER TABLE"})) {
                                createRegex = "CREATE[\\s]*TABLE[\\s\\S]*MDIY_FORM_" + modelJsonBean.getTableName().toUpperCase();
                                alterRegex = "ALTER[\\s]*TABLE[\\s\\S]*MDIY_FORM_" + modelJsonBean.getTableName().toUpperCase();
                                createPattern = Pattern.compile(createRegex);
                                alterPattern = Pattern.compile(alterRegex);
                                if (createPattern.matcher(sql.toUpperCase()).find() || alterPattern.matcher(sql.toUpperCase()).find()) {
                                    this.modelDao.excuteSql(sql);
                                    continue;
                                }
                            }

                            if (!StringUtils.isBlank(sql) && !StrUtil.containsAnyIgnoreCase(sql, new CharSequence[]{"INSERT ", "SELECT ", "UPDATE ", "DELETE ", "DROP ", "ALTER ", "TRUNCATE ", "RENAME ", "UNIQUE_LINK_ID`(`LINK_ID`)", "UNIQUE(\"LINK_ID\")", "DROP TABLE "}) || sql.indexOf("CREATE") >= 0) {
                                sql = sql.replace("FROM dual", "FROM dual;").replace(" END", " END;");

                                try {
                                    this.modelDao.excuteSql(sql);
                                } catch (Exception var19) {
                                    this.LOG.debug("恶意执行 sql: {}", sql);
                                    var19.printStackTrace();
                                }

                                this.LOG.debug(sql);
                            }
                        }
                    }

                    if (StringUtils.isNotBlank(tmpSql)) {
                        this.modelDao.excuteSql(tmpSql);
                    }

                    Map json = new HashMap();
                    json.put("html", modelJsonBean.getHtml());
                    json.put("searchJson", modelJsonBean.getSearchJson());
                    json.put("script", modelJsonBean.getScript());
                    json.put("isWebSubmit", modelJsonBean.isWebSubmit());
                    json.put("isWebCode", modelJsonBean.isWebCode());
                    json.put("sql", modelJsonBean.getSql());
                    json.put("tableName", modelJsonBean.getTableName());
                    model.setModelField(modelJsonBean.getField());
                    model.setModelType(modelType);
                    model.setModelJson(JSONUtil.toJsonStr(json));
                    super.save(model);
                    return true;
                }
            }
        } else {
            return false;
        }
    }

    public boolean updateConfig(String modelId, ModelJsonBean modelJsonBean) {
        return !StringUtils.isEmpty(modelId) && modelJsonBean != null ? this.updateConfig(modelId, modelJsonBean, "") : false;
    }

    public boolean updateConfig(String modelId, ModelJsonBean modelJsonBean, String modelType) {
        if (!StringUtils.isEmpty(modelId) && modelJsonBean != null) {
            ModelEntity modelEntity = (ModelEntity) super.getById(modelId);
            if (ObjectUtil.isNull(modelEntity)) {
                return false;
            } else {
                ModelEntity model = new ModelEntity();
                model.setModelName(modelJsonBean.getTitle());
                model.setModelCustomType(modelEntity.getModelCustomType());
                ModelEntity oldModel = (ModelEntity) super.getOne(new QueryWrapper(model));
                if (ObjectUtil.isNotNull(oldModel) && !modelEntity.getId().equals(oldModel.getId())) {
                    return false;
                } else {
                    String oldTableName = modelEntity.getModelTableName();
                    String rename = "ALTER  TABLE {} RENAME TO {};";
                    if (modelEntity.getModelCustomType().equalsIgnoreCase(ModelCustomTypeEnum.MODEL.getLabel())) {
                        modelEntity.setModelTableName(("MDIY_MODEL_" + modelJsonBean.getTableName()).toUpperCase());
                        this.updateTable(modelEntity.getModelField(), modelJsonBean.getField(), modelEntity.getModelTableName());
                        if (!oldTableName.equals(modelEntity.getModelTableName())) {
                            rename = StrUtil.format(rename, new Object[]{oldTableName, modelEntity.getModelTableName()});
                            if (StringUtils.isNotBlank(rename) && !StrUtil.containsAnyIgnoreCase(rename, new CharSequence[]{"INSERT ", "SELECT ", "UPDATE ", "DELETE ", "DROP ", "TRUNCATE ", "RENAME "})) {
                                this.modelDao.excuteSql(rename);
                            }
                        }
                    }

                    if (modelEntity.getModelCustomType().equalsIgnoreCase(ModelCustomTypeEnum.FORM.getLabel())) {
                        modelEntity.setModelTableName(("MDIY_FORM_" + modelJsonBean.getTableName()).toUpperCase());
                        if (!oldTableName.equals(modelEntity.getModelTableName())) {
                            throw new BusinessException(BundleUtil.getBaseString("err.error", new String[]{BundleUtil.getString("net.mingsoft.mdiy.resources.resources", "table.name", new String[0])}));
                        }

                        this.updateTable(modelEntity.getModelField(), modelJsonBean.getField(), modelEntity.getModelTableName());
                    }

                    Map json = new HashMap();
                    json.put("html", modelJsonBean.getHtml());
                    json.put("searchJson", modelJsonBean.getSearchJson());
                    json.put("script", modelJsonBean.getScript());
                    json.put("isWebSubmit", modelJsonBean.isWebSubmit());
                    json.put("isWebCode", modelJsonBean.isWebCode());
                    json.put("sql", modelJsonBean.getSql());
                    json.put("form", modelJsonBean.getForm());
                    json.put("tableName", modelJsonBean.getTableName());
                    modelEntity.setModelField(modelJsonBean.getField());
                    modelEntity.setModelName(modelJsonBean.getTitle());
                    modelEntity.setModelType(modelType);
                    modelEntity.setModelJson(JSONUtil.toJsonStr(json));
                    super.updateById(modelEntity);
                    List<Map> mapList = JSONUtil.toList(JSONUtil.parseArray(modelJsonBean.getField()), Map.class);
                    List<String> fieldList = (List) mapList.stream().map((mapx) -> {
                        return StrUtil.toCamelCase(mapx.get("field").toString().toLowerCase());
                    }).collect(Collectors.toList());
                    fieldList.add("linkId");
                    fieldList.add("modelId");
                    ConfigEntity configEntity = (ConfigEntity) this.configBiz.getOne((Wrapper) (new QueryWrapper()).eq("config_name", modelEntity.getModelName()));
                    Map<String, Object> map = ConfigUtil.getMap(modelEntity.getModelName());
                    if (CollUtil.isNotEmpty(map)) {
                        Object[] keys = map.keySet().toArray();
                        Object[] var15 = keys;
                        int var16 = keys.length;

                        for (int var17 = 0; var17 < var16; ++var17) {
                            Object key = var15[var17];
                            if (!fieldList.contains(key)) {
                                map.remove(key);
                            }
                        }

                        configEntity.setConfigData(JSONUtil.toJsonStr(map));
                        this.configBiz.updateById(configEntity);
                    }

                    return true;
                }
            }
        } else {
            return false;
        }
    }

    public boolean delete(List<String> ids) {
        Iterator var2 = ids.iterator();

        while (var2.hasNext()) {
            String id = (String) var2.next();
            ModelEntity modelEntity = (ModelEntity) super.getById(id);
            boolean flag = super.removeById(id);
            if (!flag) {
                this.LOG.debug("{}删除失败", modelEntity.getModelTableName());
                break;
            }

            try {
                this.modelDao.dropTable(modelEntity.getModelTableName());
            } catch (Exception var7) {
                this.LOG.debug("{}表不存在", modelEntity.getModelTableName());
                var7.printStackTrace();
            }
        }

        return true;
    }

    private void updateTable(String oldStr, String newStr, String tableName) {
        List<Dict> oldList = JSONUtil.toList(oldStr, Dict.class);
        List<Dict> newList = JSONUtil.toList(newStr, Dict.class);
        StringBuffer stringBuffer = new StringBuffer();
        Collection<Dict> disMap = CollUtil.disjunction(oldList, newList);
        if (CollUtil.isNotEmpty(disMap)) {
            Collection<Dict> oldIntersection = CollUtil.intersection(oldList, disMap);
            String alertTable = "";
            stringBuffer.append(alertTable);
            if (CollUtil.isNotEmpty(oldIntersection)) {
                String dropSql = StrUtil.format("ALTER TABLE {} ", new Object[]{tableName.toUpperCase()}).concat("DROP COLUMN {};");
                List<String> dropList = (List) oldIntersection.stream().map((dict) -> {
                    return StrUtil.format(dropSql, new Object[]{dict.getStr("field")});
                }).collect(Collectors.toList());
                stringBuffer.append(CollUtil.join(dropList, ";"));
            }

            Collection<Dict> newIntersection = CollUtil.intersection(newList, disMap);
            if (CollUtil.isNotEmpty(newIntersection)) {
                if (CollUtil.isNotEmpty(oldIntersection)) {
                    stringBuffer.append(";");
                }

                String addSql = StrUtil.format("ALTER TABLE {} ", new Object[]{tableName.toUpperCase()}).concat("ADD ( {} {}({}) NULL);");
                List<String> addList = (List) newIntersection.stream().map((dict) -> {
                    return StrUtil.format(addSql, new Object[]{dict.getStr("field"), dict.getStr("jdbcType"), dict.getStr("length")}).replaceAll("\\(0\\)", "");
                }).collect(Collectors.toList());
                stringBuffer.append(CollUtil.join(addList, ";"));
            }

            stringBuffer.append(";");
            this.LOG.debug("执行的SQL{}", stringBuffer);
            String[] formSqls = stringBuffer.toString().split(";");
            String[] var19 = formSqls;
            int var13 = formSqls.length;

            for (int var14 = 0; var14 < var13; ++var14) {
                String sql = var19[var14];
                if (!StringUtils.isBlank(sql) && !StrUtil.containsAnyIgnoreCase(sql, new CharSequence[]{"SELECT ", "INSERT ", "DELETE ", "DELETE "})) {
                    this.modelDao.excuteSql(sql);
                }
            }
        }

    }
}
